<template>
  <div class="editorContainer">
    <div class="code-name">{{ name }}:</div>
    <div ref="editorContainer" class="cm-editor"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, defineProps, defineEmits } from "vue";
import { EditorView, basicSetup } from "codemirror";
import { cpp } from "@codemirror/lang-cpp";
import { oneDark } from "@codemirror/theme-one-dark";
import * as autocomplete from "@codemirror/autocomplete";
import { EditorState } from "@codemirror/state";
import { insertTab, indentMore, indentLess } from "@codemirror/commands";
import { keymap } from "@codemirror/view";

const customKeymap = keymap.of([
  { key: "Tab", run: insertTab },         // Tab 键插入制表符
  { key: "Shift-Tab", run: indentLess }, // Shift+Tab 减少缩进
  { key: "Ctrl-i", run: indentMore },    // Ctrl+i 增加缩进
]);

const emit = defineEmits(["update:code"]);
const props = defineProps({
  code: String,
  name: String,
});

const { autocompletion } = autocomplete;
const cppKeywords = [
  "auto",
  "break",
  "case",
  "char",
  "const",
  "continue",
  "default",
  "do",
  "double",
  "else",
  "enum",
  "extern",
  "float",
  "for",
  "goto",
  "if",
  "int",
  "long",
  "register",
  "return",
  "short",
  "signed",
  "sizeof",
  "static",
  "struct",
  "switch",
  "typedef",
  "union",
  "unsigned",
  "void",
  "volatile",
  "while",
  "vec2",
  "vec3",
  "vec4",
  "main",
  "uniform",
  "cin",
  "cout",
  "uv",
  "gl_FragColor",
  "distance",
  "step",
  "mod",
  "floor",
  "ceil",
  "frac",
  "fmod",
  "modf",
  "saturate",
  "clamp",
  "sign"
];

const editor = ref(null);
const editorContainer = ref(null);

function cppCompletion(context) {
  let word = context.matchBefore(/\w*/);
  if (word.from == word.to && !context.explicit) return null;

  const variables = extractVariables(context.state); // 提取变量

  return {
    from: word.from,
    options: Array.from(new Set(variables, cppKeywords)).map((keyword) => ({
      label: keyword,
      type: "keyword",
    })),
  };
}

// 从当前编辑器状态中提取已定义的变量
function extractVariables(state) {
  const variables = [];

  // 这里可以通过自定义逻辑提取变量
  // 例如：遍历代码并识别函数、类、局部变量等
  const doc = state.doc.text;
  doc.forEach((line, lineNo) => {
    const matches = line.match(/\b\w+\b/g); // 匹配所有的单词
    if (matches) {
      variables.push(...matches);
    }
  });

  return [...new Set(variables)]; // 去重
}

onMounted(() => {
  let view = new EditorView({
    state: EditorState.create({
      doc: props.code,
      extensions: [
        basicSetup,
        cpp(),
        oneDark,
        customKeymap,
        autocompletion({ override: [cppCompletion] }), // 添加自动补全
        EditorView.updateListener.of((update) => {
          if (update.docChanged) {
            const newValue = update.state.doc.toString();
            emit("update:code", newValue);
          }
        }),
      ],
    }),
    parent: editorContainer.value,
  });
  editor.value = view;
  console.log("view ---->", view);
});
</script>

<style scoped>
.editorContainer {
  height: 100%;
  text-align: left;
}

.editorContainer .cm-editor {
  height: calc(100% - 30px);
}
.code-name {
  height: 30px;
  background-color: #292c33;
  color: #fff;
  line-height: 30px;
  box-sizing: border-box;
  padding-left: 12px;
}
</style>
